#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/ioctl.h>

//#define WATCHDOG_DEAMON			1

#ifndef WATCHDOG_DEAMON
#define WATCHDOG_DEBUG			1
#endif

#define	WATCHDOG_IOCTL_BASE		'W'
#define	WDIOC_KEEPALIVE			_IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define	WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define	WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)

int main(void)
{
	int ret = 0;

#ifdef WATCHDOG_DEAMON
	int i = 0;
	int base_fd[3] = {0, 0, 0};

	pid_t pid = 0;
#else
#ifdef WATCHDOG_DEBUG
	int timeout = 0;
#endif
#endif

	int watchdog_fd = 0;

#ifdef WATCHDOG_DEAMON
	pid = fork();
	if(0 == pid)
	{
		setsid();
		pid = fork();
		if(0 == pid)
		{
			setsid();
			chdir("/");
			umask(0);

			for(i = 0; 1024 > i; i++)
			{
				close(i);
			}

			base_fd[0] = open("/dev/null", O_RDWR);
			base_fd[1] = dup(0);
			base_fd[2] = dup(0);
			
			if(0 != base_fd[0] || 1 != base_fd[1] || 2 != base_fd[2])
			{
				ret = -1;
			}
			else
			{
				watchdog_fd = open("/dev/watchdog", O_WRONLY);

				if(0 > watchdog_fd)
				{
					ret = -1;
				}
				else
				{
					while(1)
					{
						ioctl(watchdog_fd, WDIOC_KEEPALIVE);
						sleep(10);
					}
					close(watchdog_fd);
					ret = 0;
				}
			}
		}
		else if(0 < pid)
		{
			ret = 0;
		}
		else
		{
			printf("second fork is failed...");
			ret = -1;
		}
	}
	else if(0 < pid)
	{
		ret = 0;
	}
	else
	{
		printf("First fork is failed...");
		ret = -1;
	}
#else
	watchdog_fd = open("/dev/watchdog", O_WRONLY);

	if(0 >= watchdog_fd)
	{
#ifdef WATCHDOG_DEBUG
		perror("watchdog");
#endif
		ret = -1;
	}
	else
	{
		while(0 == ret)
		{
#ifdef WATCHDOG_DEBUG
			if(0 != ioctl(watchdog_fd, WDIOC_GETTIMEOUT, &timeout))
			{
				perror("ioctl");
				ret = -1;
				break;
			}
			else
			{
				printf("watchdog keepalive, timeout = %d, retval = %d\n", timeout, ioctl(watchdog_fd, WDIOC_KEEPALIVE));
			}
#else
			ioctl(watchdog_fd, WDIOC_KEEPALIVE);
#endif
			sleep(10);
		}
		close(watchdog_fd);
	}
#endif
	return ret;
}



